/*
 * FreeModbus Libary: STR71x Port
 * Copyright (C) 2006 Christian Walter <wolti@sil.at>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * File: $Id$
 */

/* ----------------------- System includes ----------------------------------*/
#include "assert.h"

/* ----------------------- FreeRTOS includes --------------------------------*/
/* ----------------------- STM32 includes ----------------------------------*/
#include "stm32f4xx.h"

/* ----------------------- Platform includes --------------------------------*/
#include "port.h"

/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"

/* ----------------------- Defines ------------------------------------------*/
#define MB_TIMER_DEV (TIM5)
#define MB_TIMER_DEV_RCC (RCC_APB1Periph_TIM5)
#define MB_TIMER_DEV_IRQN (TIM5_IRQn)
#define MB_TIMER_DEV_IRQHandler TIM5_IRQHandler

/* ----------------------- Static functions ---------------------------------*/

/* ----------------------- Start implementation -++----------------------------*/
BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(MB_TIMER_DEV_RCC, ENABLE); // 时钟使能

    TIM_TimeBaseStructure.TIM_Period =
            (50 * usTim1Timerout50us) - 1; // 设置在下一个更新事件装入活动的自动重装载寄存器周期的值:49为50us
    TIM_TimeBaseStructure.TIM_Prescaler = 83; // 设置用来作为TIMx时钟频率除数的预分频值 1MHz(1us) 的计数频率
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;                // 设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM向上计数模式
    TIM_TimeBaseInit(MB_TIMER_DEV,
                     &TIM_TimeBaseStructure); // 根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

    TIM_ITConfig(MB_TIMER_DEV, TIM_IT_Update, ENABLE);
    NVIC_InitStructure.NVIC_IRQChannel = MB_TIMER_DEV_IRQN; // TIMx中断

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 先占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        // 从优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure); // 根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

    TIM_SetCounter(MB_TIMER_DEV, 0);
    TIM_Cmd(MB_TIMER_DEV, DISABLE); // 使能TIMx外设
    return TRUE;
}

void MB_TIMER_DEV_IRQHandler(void)
{
    if (TIM_GetITStatus(MB_TIMER_DEV, TIM_IT_Update) != RESET)
    {
        (void)pxMBPortCBTimerExpired();
        TIM_ClearITPendingBit(MB_TIMER_DEV, TIM_IT_Update);
    }
}

inline void vMBPortTimersEnable()
{
    TIM_ClearITPendingBit(MB_TIMER_DEV, TIM_IT_Update);
    TIM_ITConfig(MB_TIMER_DEV, TIM_IT_Update, ENABLE);
    TIM_SetCounter(MB_TIMER_DEV, 0x0000);
    TIM_Cmd(MB_TIMER_DEV, ENABLE);
}

inline void vMBPortTimersDisable()
{
    TIM_ClearITPendingBit(MB_TIMER_DEV, TIM_IT_Update);
    TIM_ITConfig(MB_TIMER_DEV, TIM_IT_Update, DISABLE);
    TIM_SetCounter(MB_TIMER_DEV, 0x0000);
    TIM_Cmd(MB_TIMER_DEV, DISABLE);
}
